package eteam.aps.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import eteam.aps.common.component.LoginUserRedisService;
import eteam.aps.common.constant.*;
import eteam.aps.common.entity.ParentEntity;
import eteam.aps.common.helper.Helper;
import eteam.aps.mapper.*;
import eteam.aps.model.entity.BaseEntity;
import eteam.aps.model.entity.ProductProcessingProgress;
import eteam.aps.model.entity.ScanProcessStep;
import eteam.aps.model.entity.other.ProcessQuality;
import eteam.aps.model.entity.other.ScanProcess;
import eteam.aps.model.entity.sale.ProductProcessOl;
import eteam.aps.model.vo.moco_rders.MocoRdersDisplayVo;
import eteam.aps.model.vo.scan.ScanInfo;
import eteam.aps.model.vo.scan.ScanMoc;
import eteam.aps.model.vo.scan.ScanProcessShow;
import eteam.aps.model.vo.working_procedure.WorkingProcedureVo;
import eteam.aps.service.ProcessQualityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 工序质检 业务 实现类
 *
 * @author LiuLei
 */
@Service
public class ProcessQualityServiceImpl implements ProcessQualityService {

    @Autowired
    private MocoRdersMapper mocoRdersMapper;

    @Autowired
    private WorkingProcedureMapper workingProcedureMapper;

    @Autowired
    private ProductNumberMapper productNumberMapper;

    @Autowired
    private SystemMapper systemMapper;

    @Autowired
    private ScanProcessStepMapper scanProcessStepMapper;

    @Autowired
    private LoginUserRedisService loginUserRedisService;

    @Autowired
    private ProductProcessOlMapper productProcessOlMapper;

    @Override
    @Transactional
    public ScanProcessShow<?> scanInfo(ScanProcess scanProcess) throws Exception {
        ScanProcessShow<Object> show = new ScanProcessShow<>();
        Map<String, Object> map = new HashMap<>(5);
        // 状态不为删除
        map.put("fState", ParentEntity.FSTATE_DELETED);
        // 当前扫描的数据
        map.put("code", scanProcess.getScan());
        // 状态
        map.put("State", -1);
        // 扫描工单？状态为小于等于正常报工【异常报工，加工中，异常报工】
        map.put("start", ProductType.ERROR);
        map.put("end", ProductType.FINISH);
        MocoRdersDisplayVo moc = mocoRdersMapper.selMocByProBarCode(map);
        // 扫描工序？
        WorkingProcedureVo wp = workingProcedureMapper.selWPSimByName(map);
        // 扫描人员？
        BaseEntity entity = systemMapper.selectEmpName(map);
        if (moc == null && wp == null && entity == null) { //暂无扫描数据
            show.setScanCode(ScanType.ERROR);
            show.setScanMsg("暂无扫描的数据！");
            return show;
        } else {
            String fuserid = loginUserRedisService.getUser().getFuserid();
            if (moc != null) {
                if (Helper.isNotEmpty(scanProcess.getWpCode())
                        && Helper.isNotEmpty(scanProcess.getScan())) {
                    Integer count = productProcessOlMapper.selectCount(new LambdaQueryWrapper<ProductProcessOl>()
                            .eq(ProductProcessOl::getfWorkCode, scanProcess.getWpCode())
                            .eq(ProductProcessOl::getfBarCode, scanProcess.getScan())
                    );
                    if (count > 0) {
                        show.setScanCode(ScanType.ERROR);
                        show.setScanMsg("该产品对应的工序已报工！");
                        return show;
                    }
                    Map<String, Object> query = new HashMap<>(3);
                    query.put("state", ParentEntity.FSTATE_DELETED);
                    query.put("check", CheckType.CHECK);
                    query.put("code", scanProcess.getWpCode());
                    String preCode = workingProcedureMapper.selectPreWorkByCode(query);
                    if (Helper.isNotEmpty(preCode)) {
                        count = productProcessOlMapper.selectCount(new LambdaQueryWrapper<ProductProcessOl>()
                                .eq(ProductProcessOl::getfWorkCode, preCode)
                                .eq(ProductProcessOl::getfBarCode, scanProcess.getScan())
                        );
                        if (count <= 0) {
                            show.setScanCode(ScanType.ERROR);
                            show.setScanMsg("该工序的前置工序" + preCode + "未完成，请先完成前置工序！");
                            return show;
                        }
                    }
                }
                //设置产品条码
                scanProcess.setBarCode(scanProcess.getScan());
                // 记录操作步骤
                ScanProcessStep scanProcessStep = setScanStep(moc, scanProcess, show);
                if (scanProcessStep != null) {
                    Helper.setDefaultAddValue(scanProcessStep, fuserid);
                    scanProcessStepMapper.addScanStep(scanProcessStep);
                }
                show.setData(new ScanMoc(scanProcess.getScan(), BeanUtil.copyProperties(moc, MocoRdersDisplayVo.class)));
            }
            // 扫描工序？工序不为空
            if (wp != null) {
                if (Helper.isNotEmpty(scanProcess.getBarCode())
                        && Helper.isNotEmpty(scanProcess.getScan())) {
                    Integer count = productProcessOlMapper.selectCount(new LambdaQueryWrapper<ProductProcessOl>()
                            .eq(ProductProcessOl::getfWorkCode, scanProcess.getScan())
                            .eq(ProductProcessOl::getfBarCode, scanProcess.getBarCode())
                    );
                    if (count > 0) {
                        show.setScanCode(ScanType.ERROR);
                        show.setScanMsg("该产品对应的工序已报工！");
                        return show;
                    }
                    Map<String, Object> query = new HashMap<>(3);
                    query.put("state", ParentEntity.FSTATE_DELETED);
                    query.put("check", CheckType.CHECK);
                    query.put("code", scanProcess.getScan());
                    String preCode = workingProcedureMapper.selectPreWorkByCode(query);
                    if (Helper.isNotEmpty(preCode)) {
                        count = productProcessOlMapper.selectCount(new LambdaQueryWrapper<ProductProcessOl>()
                                .eq(ProductProcessOl::getfWorkCode, preCode)
                                .eq(ProductProcessOl::getfBarCode, scanProcess.getBarCode())
                        );
                        if (count <= 0) {
                            show.setScanCode(ScanType.ERROR);
                            show.setScanMsg("该工序的前置工序" + preCode + "未完成，请先完成前置工序！");
                            return show;
                        }
                    }
                }
                scanProcess.setWpCode(wp.getfCode());
                scanProcess.setWpName(wp.getfName());
                // 记录操作步骤
                ScanProcessStep scanProcessStep = setScanStep(wp, scanProcess, show);
                if (scanProcessStep != null) {
                    Helper.setDefaultAddValue(scanProcessStep, fuserid);
                    scanProcessStepMapper.addScanStep(scanProcessStep);
                }
                show.setData(new ScanInfo(wp.getfCode(), wp.getfName()));
            }
            // 扫描人员？人员不为空
            if (entity != null) {
                scanProcess.setUserCode(entity.getId());
                scanProcess.setUserName(entity.getName());
                // 记录操作步骤
                ScanProcessStep scanProcessStep = setScanStep(entity, scanProcess, show);
                if (scanProcessStep != null) {
                    Helper.setDefaultAddValue(scanProcessStep, fuserid);
                    scanProcessStepMapper.addScanStep(scanProcessStep);
                }
                show.setData(new ScanInfo(entity.getId(), entity.getName()));
            }
        }
        return show;
    }


    @Autowired
    private ProductProcessingProgressMapper productProcessingProgressMapper;

    @Override
    @Transactional
    public ScanProcessShow<MocoRdersDisplayVo> submit(ProcessQuality processQuality) throws Exception {
        ScanProcessShow<MocoRdersDisplayVo> show = new ScanProcessShow<>();
        if (Helper.isNotEmpty(processQuality.getBarCode()) && Helper.isNotEmpty(processQuality.getWpCode())) {
            Integer count = productProcessOlMapper.selectCount(new LambdaQueryWrapper<ProductProcessOl>()
                    .eq(ProductProcessOl::getfBarCode, processQuality.getBarCode())
                    .eq(ProductProcessOl::getfWorkCode, processQuality.getWpCode()));
            if (count > 0) {
                show.setScanCode(ScanType.ERROR);
                show.setScanMsg("该产品对应的工序已报工！不能重复报工！");
                return show;
            }
        }
        // 报工状态
        int code = processQuality.getScan().equals("00") ? ProductType.FINISH : ProductType.ERROR;
        ScanProcessStep scanProcessStep = new ScanProcessStep(
                processQuality.getBarCode(),
                processQuality.getWpCode(),
                processQuality.getWpName(),
                processQuality.getUserCode(),
                processQuality.getUserName(),
                LocalDateTime.now(),
                processQuality.getScan().equals("00") ? StepType.OK : StepType.NO,
                code,
                processQuality.getBusinessType()
        );
        String fuserid = loginUserRedisService.getUser().getFuserid();
        Helper.setDefaultAddValue(scanProcessStep, fuserid);
        // 保存当前报工的工序
        if (code == ProductType.FINISH) {
            ProductProcessOl ol = new ProductProcessOl();
            ol.setfBarCode(processQuality.getBarCode());
            ol.setfWorkCode(processQuality.getWpCode());
            Helper.setDefaultAddValue(ol, fuserid);
            productProcessOlMapper.insert(ol);
        }
        // 保存操作步骤
        scanProcessStepMapper.addScanStep(scanProcessStep);
        // 修改产品状态  --- 备注
        Map<String, Object> map = new HashMap<>(5);
        map.put("barCode", processQuality.getBarCode());
        map.put("code", code);
        map.put("remark", processQuality.getRemark());
        map.put("modify", fuserid);
        map.put("time", LocalDateTime.now());
        productNumberMapper.updateProByBarCode(map);
        map.clear();
        // 状态不为删除
        map.put("fState", ParentEntity.FSTATE_DELETED);
        // 当前扫描的数据
        map.put("code", processQuality.getBarCode());
        // 扫描工单？状态为小于等于正常报工【异常报工，加工中，异常报工】
        map.put("start", code);
        map.put("end", code);
        MocoRdersDisplayVo moc = mocoRdersMapper.selMocByProBarCode(map);
        show.setScanMsg("报工成功！");
        show.setData(moc);

        //保存到加工进度表中
        ProductProcessingProgress productProcessingProgress = new ProductProcessingProgress();

        Helper.setDefaultAddValue(productProcessingProgress, fuserid);
        productProcessingProgress.setfRemark(processQuality.getRemark());
        productProcessingProgress.setFGoodOrNot(processQuality.getfGoodOrNot());
        productProcessingProgress.setFResponsibleDepartment(processQuality.getfResponsibleDepartment());
        productProcessingProgress.setFPeopleInCharge(processQuality.getfPeopleInCharge());
        productProcessingProgress.setFPeopleInMutualInspection(processQuality.getfPeopleInMutualInspection());
        productProcessingProgress.setFPCQInspection(processQuality.getfPCQInspection());
        productProcessingProgress.setFQuestionClassification(processQuality.getfQuestionClassification());
        productProcessingProgress.setFEquipmentNumber(processQuality.getfEquipmentNumber());
        productProcessingProgress.setFReason(processQuality.getfReason());
        productProcessingProgress.setFHandlingMethod(processQuality.getfHandlingMethod());
        productProcessingProgress.setFHandler(processQuality.getfHandler());
        productProcessingProgress.setFQCConfirmor(processQuality.getfQCConfirmor());
        productProcessingProgress.setFHandlingInformation(processQuality.getfHandlingInformation());
        productProcessingProgress.setFBusinessType(processQuality.getBusinessType());
        productProcessingProgress.setFInvCode(processQuality.getInvCode());
        productProcessingProgress.setFBarCode(processQuality.getBarCode());
        productProcessingProgress.setFWpCode(processQuality.getWpCode());
        productProcessingProgress.setFOpCode(processQuality.getUserCode());
        productProcessingProgress.setFReportWork(processQuality.getScan());
        productProcessingProgress.setFCustomer(processQuality.getCustomer());
        productProcessingProgress.setFProductType(processQuality.getProductType());
        productProcessingProgressMapper.insert(productProcessingProgress);
        return show;
    }

    /**
     * 设置扫描步骤
     */
    public ScanProcessStep setScanStep(Object obj, ScanProcess scanProcess, ScanProcessShow<?> show) {
        if (obj instanceof MocoRdersDisplayVo) {
            if (Helper.isNotEmpty(scanProcess.getBarCode())) {
                // 工单 返回的对象 不同
                show.setScanCode(ScanType.MOC);
                show.setScanMsg("工单扫描成功！");
                return new ScanProcessStep(
                        scanProcess.getBarCode(), scanProcess.getWpCode(), scanProcess.getWpName(),
                        scanProcess.getUserCode(), scanProcess.getUserName(), LocalDateTime.now(),
                        StepType.MOC, ProductType.PROCESSING, scanProcess.getBusinessType()
                );
            } else {
                show.setScanCode(ScanType.ERROR);
                show.setScanMsg("产品条码不能为空！");
            }
        } else if (obj instanceof WorkingProcedureVo) {
            if (Helper.isEmpty(scanProcess.getWpCode())) {
                show.setScanCode(ScanType.ERROR);
                show.setScanMsg("工序编号不能为空!");
            } else if (Helper.isEmpty(scanProcess.getWpName())) {
                show.setScanCode(ScanType.ERROR);
                show.setScanMsg("工序名称不能为空!");
            } else {
                show.setScanCode(ScanType.WP);
                show.setScanMsg("工序扫描成功！");
                return new ScanProcessStep(
                        scanProcess.getBarCode(), // 条码号
                        scanProcess.getWpCode(),  // 工序编号
                        scanProcess.getWpName(), // 工序名称
                        scanProcess.getUserCode(), // 操作员编号
                        scanProcess.getUserName(), // 操作员名称
                        LocalDateTime.now(), // 当前时间
                        StepType.WP, // 操作步骤
                        ProductType.PROCESSING, // 产品进程
                        scanProcess.getBusinessType()
                );
            }
        } else {
            if (Helper.isEmpty(scanProcess.getUserCode())) {
                show.setScanCode(ScanType.ERROR);
                show.setScanMsg("操作员编号不能为空!");
            } else if (Helper.isEmpty(scanProcess.getUserName())) {
                show.setScanCode(ScanType.ERROR);
                show.setScanMsg("操作员不能为空！");
            } else {
                show.setScanCode(ScanType.OP);
                show.setScanMsg("操作员扫描成功！");
                return new ScanProcessStep(
                        scanProcess.getBarCode(), scanProcess.getWpCode(), scanProcess.getWpName(),
                        scanProcess.getUserCode(), scanProcess.getUserName(), LocalDateTime.now(),
                        StepType.OP, ProductType.PROCESSING, scanProcess.getBusinessType()
                );
            }
        }
        return null;
    }
}
